package com.ethink.platform.controller.order;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ethink.framework.common.web.BaseController;
import com.ethink.framework.common.web.context.SPRequestContextHolder;
import com.ethink.framework.common.web.response.CommonResponse;
import com.ethink.mdm.api.component.MdmComponent;
import com.ethink.mdm.api.info.CurrencyInfo;
import com.ethink.order.api.PurchaseOrderFacade;
import com.ethink.order.api.SaleDemandOrderFacade;
import com.ethink.order.api.info.PurchaseOrderDetailInfo;
import com.ethink.order.api.info.SaleDemandOrderDetailInfo;
import com.ethink.order.api.info.SaleDemandOrderInfo;
import com.ethink.order.api.model.*;
import com.ethink.order.api.request.*;
import com.ethink.order.api.response.PurchaseOrderDetailQueryResponse;
import com.ethink.order.api.response.TransferPurchaseResponse;
import com.ethink.platform.controller.order.info.ExportInfo;
import com.ethink.platform.manager.ExportManager;
import com.ethink.platform.manager.PurchaseManager;
import com.ethink.system.api.SystemFileFacade;
import com.ethink.system.api.SystemTodoFacade;
import com.ethink.system.api.enums.SystemTodoTodoTypeEnum;
import com.ethink.system.api.info.SystemFileInfo;
import com.ethink.system.api.request.SystemTodoAddRequest;
import com.ethink.warehouse.api.LogisticsTraceApplyOrderFacade;
import com.ethink.warehouse.api.MateInventoryDetailOrderFacade;
import com.ethink.warehouse.api.SubWarehouseFacade;
import com.ethink.warehouse.api.enums.SubjectEnum;
import com.ethink.warehouse.api.info.MateInventoryDetailOrderMoreInfo;
import com.ethink.warehouse.api.info.SubWarehouseInfo;
import com.ethink.warehouse.api.request.LogisticsTraceApplyDetailListRequest;
import com.ethink.warehouse.api.request.LogisticsTraceApplyUpdateRequest;
import com.ethink.warehouse.api.request.MateInventoryDetailOrderQueryRequest;
import com.ethink.warehouse.api.response.LogisticsTraceApplyDetailOrderGetDetailResponse;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 采购单 Controller
 *
 * @author default
 * @date 2022-10-31
 */
@Tag(name = "PurchaseOrderController", description = "采购单 Controller")
@RestController
@Slf4j
@RequestMapping("platform-server/v1/order-service")
public class PurchaseOrderController extends BaseController {

    @Autowired
    private PurchaseOrderFacade purchaseOrderFacade;

    @Autowired
    private SaleDemandOrderFacade saleDemandOrderFacade;

    @Autowired
    private PurchaseManager purchaseManager;

    @Autowired
    private SubWarehouseFacade subWarehouseFacade;

    @Autowired
    private SystemFileFacade systemFileFacade;

    @Autowired
    private SystemTodoFacade systemTodoFacade;

    @Autowired
    private MdmComponent mdmComponent;

    @Autowired
    private MateInventoryDetailOrderFacade mateInventoryDetailOrderFacade;

    @Autowired
    private LogisticsTraceApplyOrderFacade logisticsTraceApplyOrderFacade;

    @Autowired
    private ExportManager exportManager;


    @Operation(summary = "预供订单分页查询")
    @GetMapping("/saleDemandDetail/preSuppleQuery")
    public CommonResponse<List<PreSuppleOrderDetailModel>> preSuppleQuery(PreSupplePageQueryRequest request) {
        request.setPurchaseUserCode(SPRequestContextHolder.getCurrentSystemUserLoginName());
        return succeedWithPage(saleDemandOrderFacade.pageQueryByPreSupple(request));
    }

    @Operation(summary = "预供报价")
    @PostMapping("/purchase/quote")
    public CommonResponse purchaseQuote(@RequestBody PurchaseQuoteRequest request) {
        request.setCreateUserCode(SPRequestContextHolder.getCurrentSystemUserLoginName());
        request.setCreateUserName(SPRequestContextHolder.getCurrentSystemUserRealName());
        for (PurchaseQuoteRequest.Item item : request.getItem()) {
            CurrencyInfo currency = mdmComponent.getCurrency(item.getCurrencyCode());
            item.setExchangeRate(currency.getUsdRate());
        }
        purchaseOrderFacade.purchaseQuote(request);
        //代办
        try {
            SaleDemandOrderInfo saleDemandOrderInfo = saleDemandOrderFacade.queryMainByOrderNo(request.getOrderNo());
            SaleDemandOrderDetailInfo saleDemandOrderDetailInfo = saleDemandOrderFacade.queryItemByDetailOrderNo(request.getDetailOrderNo());
            SystemTodoAddRequest addRequest = new SystemTodoAddRequest();
            addRequest.setUserCode(saleDemandOrderInfo.getCreateUserCode());
            addRequest.setUserName(saleDemandOrderInfo.getCreateUserName());
            addRequest.setDataId(request.getDetailOrderNo());
            addRequest.setTodoType(SystemTodoTodoTypeEnum.T2.getIntValue());
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("orderNo", request.getOrderNo());
            jsonObject.put("mateSkuName", saleDemandOrderDetailInfo.getMateSkuName());
            addRequest.setTodoMessage(jsonObject.toJSONString());
            systemTodoFacade.addSystemTodo(addRequest);
        } catch (Exception e) {
            log.error("预供报价生成代办失败,需求单号:{}", request.getOrderNo());
        }
        return succeed();
    }

    @Operation(summary = "转采购单(转采购单跳转页面调用该接口.返回页面展示数据)")
    @PostMapping("/purchase/transfer")
    public CommonResponse<TransferPurchaseResponse> transferPurchaseOrder(@RequestBody @Validated TransferPurchaseOrderRequest request) {
        request.setCreateUserCode(SPRequestContextHolder.getCurrentSystemUserLoginName());
        return succeedWith(purchaseOrderFacade.transfer(request));
    }

    @Operation(summary = "新增采购单")
    @PostMapping("/purchase/add")
    public CommonResponse purchaseOrderAdd(@Validated @RequestBody PurchaseOrderAddRequest request) {
        request.setCreateUserCode(SPRequestContextHolder.getCurrentSystemUserLoginName());
        request.setCreateUserName(SPRequestContextHolder.getCurrentSystemUserRealName());
        PurchaseOrderDetailInfo purchaseOrderDetailInfo = purchaseOrderFacade.queryDetailInfoByDetailId(request.getIds().get(0));
        SubWarehouseInfo subWarehouse = subWarehouseFacade.getSubWarehouseByCode(request.getSubWarehouseCode());
        request.setSubWarehouseName(subWarehouse.getSubWarehouseName());
        CurrencyInfo currency = mdmComponent.getCurrency(purchaseOrderDetailInfo.getCurrencyCode());
        request.setCurrencyName(currency.getName());
        request.setCurrencyCode(currency.getCode());
        request.setExchangeRate(currency.getUsdRate());
        purchaseOrderFacade.add(request);
        return succeed();
    }


    @Operation(summary = "转采购单详情添加(查询)")
    @GetMapping("/purchase/preAdd")
    public CommonResponse<List<PurchaseOrderDetailModel>> queryPrePurchaseOrder(PrePurchaseOrderQueryRequest request) {
        request.setCreateUserCode(SPRequestContextHolder.getCurrentSystemUserLoginName());
        return succeedWith(purchaseOrderFacade.queryPrePurchaseOrder(request));
    }


    @Operation(summary = "采购预供管理分页查询")
    @GetMapping("/purchase/queryDetail")
    public CommonResponse<List<PurchaseOrderDetailModel>> queryPurchaseDetail(PurchaseOrderDetailPageQueryRequest request) {
        return succeedWithPage(purchaseOrderFacade.queryPurchaseDetail(request));
    }

    @Operation(summary = "采购预供管理修改")
    @PutMapping("/purchase/detail/update")
    public CommonResponse purchaseDetailUpdate(@Validated @RequestBody PurchaseOrderDetailUpdateRequest request) {
        purchaseOrderFacade.purchaseDetailUpdate(request);
        return succeed();
    }

    @Operation(summary = "采购订单分页查询")
    @GetMapping("/purchase/pageQuery")
    public CommonResponse<List<PurchaseOrderModel>> purchaseOrderPageQuery(PurchaseOrderPageQueryRequest request) {
        Page<PurchaseOrderModel> page = purchaseOrderFacade.purchaseOrderPageQuery(request);
        MateInventoryDetailOrderQueryRequest queryRequest = new MateInventoryDetailOrderQueryRequest();
        List<String> orderNoList = CollUtil.getFieldValues(page.getRecords(), "orderNo", String.class);
        queryRequest.setSourceOrderNoList(orderNoList);
        queryRequest.setSourceOrderType(SubjectEnum.T11.getCode());
        List<MateInventoryDetailOrderMoreInfo> infoList = mateInventoryDetailOrderFacade.listMateInventoryDetailOrder(queryRequest);
        Map<String, Integer> map = new HashMap<>();
        for (MateInventoryDetailOrderMoreInfo moreInfo : infoList) {
            map.put(moreInfo.getSourceOrderNo(), moreInfo.getMateTotalQty());
        }
        //差异数量 = 采购数量 - 少货数量 - 入库数量
        page.getRecords().stream().forEach(
                a -> {
                    Optional.ofNullable(map.get(a.getOrderNo())).ifPresent(
                            b -> {
                                a.setInboundQuantity(b);
                                a.setDifferenceQuantity(a.getPurchaseTotal() - b - a.getMissingQuantity());
                            }
                    );
                }
        );
        return succeedWithPage(page);
    }

    @Operation(summary = "采购订单货品模式分页查询")
    @GetMapping("/purchase/pageQueryMode")
    public CommonResponse<List<PurchaseOrderModeModel>> purchaseOrderPageModeQuery(PurchaseOrderPageQueryModeRequest request) {
        Page<PurchaseOrderModeModel> purchaseOrderModeModelPage = purchaseOrderFacade.purchaseOrderPageModeQuery(request);
        return succeedWithPage(purchaseOrderModeModelPage);
    }

    @Operation(summary = "采购订单分页查询导出")
    @GetMapping("/purchase/exportPurchase")
    public CommonResponse<ExportInfo> exportPurchase(PurchaseOrderPageQueryRequest request) {
        return succeedWith(exportManager.exportPurchase(request));
    }

    @Operation(summary = "采购订单货品模式分页查询导出")
    @GetMapping("/purchase/exportPurchaseMode")
    public CommonResponse<ExportInfo> exportPurchaseMode(PurchaseOrderPageQueryModeRequest request) {
        return succeedWith(exportManager.exportPurchaseMode(request));
    }

    @Operation(summary = "采购预供管理删除")
    @DeleteMapping("/purchase/detail/delete/{id}")
    public CommonResponse purchaseDetailDelete(@PathVariable("id") Long id) {
        purchaseOrderFacade.purchaseDetailDelete(id);
        return succeed();
    }


    @Operation(summary = "采购订单详情")
    @GetMapping("/purchase/query/{id}")
    public CommonResponse<PurchaseOrderDetailQueryResponse> purchaseOrderQueryDetail(@PathVariable Long id) {
        PurchaseOrderDetailQueryResponse response = purchaseOrderFacade.queryPurchaseOrderDetail(id);
        List<String> fileIdList = new ArrayList<>();
        PurchaseOrderWithPayModel model = response.getMain();
        //!null处理
        Optional<PurchaseOrderWithPayModel> main = Optional.ofNullable(model);
        main.ifPresent(a -> {
            LogisticsTraceApplyDetailListRequest applyDetailListRequest = new LogisticsTraceApplyDetailListRequest();
            applyDetailListRequest.setSourceOrderType(SubjectEnum.T11.getCode());
            applyDetailListRequest.setSourceOrderNo(a.getOrderNo());
            applyDetailListRequest.setSourceDetailOrderNoList(response.getItem().stream()
                    .map(PurchaseDetailModel::getDetailOrderNo).collect(Collectors.toList()));
            List<LogisticsTraceApplyDetailOrderGetDetailResponse> logisticsResponses =
                    logisticsTraceApplyOrderFacade.listLogisticsTraceApplyDetailOrder(applyDetailListRequest);
            if (CollUtil.isNotEmpty(logisticsResponses)) {
                a.setIsUpdate(false);
            }
            SubWarehouseInfo subWarehouseInfo = subWarehouseFacade.getSubWarehouseByCode(a.getSubWarehouseCode());
            a.setWarehouseCode(subWarehouseInfo.getWarehouseCode());
            a.setWarehouseName(subWarehouseInfo.getWarehouseName());
            if (a.getBankTradeFileId() != null) {
                fileIdList.add(a.getBankTradeFileId());
            }
            if (a.getPayInvoiceFileId() != null) {
                fileIdList.add(a.getPayInvoiceFileId());
            }
            if (a.getPurchaseQualification() != null) {
                fileIdList.add(a.getPurchaseQualification());
            }
        });
        if (fileIdList.size() > 0) {
            Map<String, SystemFileInfo> fileInfoMap = systemFileFacade.selectMapByFileIds(fileIdList);
            if (model.getBankTradeFileId() != null) {
                model.setBankTradeUrl(fileInfoMap.get(model.getBankTradeFileId()).getUrl());
            }
            if (model.getPayInvoiceFileId() != null) {
                model.setPayInvoiceUrl(fileInfoMap.get(model.getPayInvoiceFileId()).getUrl());
            }
            if (model.getPurchaseQualification() != null) {
                model.setPurchaseQualificationUrl(fileInfoMap.get(model.getPurchaseQualification()).getUrl());
            }
        }
        return succeedWith(response);
    }

    @Operation(summary = "采购订单信息完善")
    @PostMapping("/purchase/refine")
    public CommonResponse purchaseOrderRefine(@RequestBody @Validated PurchaseOrderRefineRequest refineRequest) {
        purchaseOrderFacade.purchaseOrderRefine(refineRequest);
        return succeed();
    }

    @Operation(summary = "采购订单修改")
    @PutMapping("/purchase/update")
    public CommonResponse purchaseOrderUpdate(@RequestBody @Validated PurchaseOrderUpdateRequest updateRequest) {
        purchaseOrderFacade.purchaseOrderUpdate(updateRequest);
        return succeed();
    }


    @Operation(summary = ("境外发货"))
    @PostMapping("/purchase/overseasDelivery/{id}")
    public CommonResponse overseasDelivery(@PathVariable("id") Long id) {
        purchaseManager.overseasDelivery(id);
        return succeed();
    }


    @Operation(summary = "预供报价查询")
    @GetMapping("purchase/quote/query")
    public CommonResponse<List<PurchaseQuoteQueryModel>> purchaseQuoteQuery(@RequestParam("detailOrderNo") String detailOrderNo) {
        String createUserCode = SPRequestContextHolder.getCurrentSystemUserLoginName();
        List<PurchaseQuoteQueryModel> models = purchaseOrderFacade.purchaseQuoteQuery(detailOrderNo, createUserCode);
        return succeedWith(models);
    }

    @Operation(summary = "采购收货仓库修改")
    @PutMapping("purchase/updateWarehouse")
    private CommonResponse purchaseWarehouse(@Validated @RequestBody PurchaseWarehouseUpdateRequest request) {
        PurchaseOrderDetailQueryResponse response = purchaseOrderFacade.queryPurchaseOrderDetail(request.getId());
        LogisticsTraceApplyUpdateRequest updateRequest = new LogisticsTraceApplyUpdateRequest();
        updateRequest.setSubWarehouseCode(request.getSubWarehouseCode());
        updateRequest.setSourceOrderType(SubjectEnum.T11.getCode());
        updateRequest.setSourceOrderNo(response.getMain().getOrderNo());
        updateRequest.setSourceDetailOrderNoList(CollUtil.getFieldValues(response.getItem(), "detailOrderNo", String.class));
        logisticsTraceApplyOrderFacade.updateLogisticsTraceApplyOrder(updateRequest);
        SubWarehouseInfo subWarehouseInfo = subWarehouseFacade.getSubWarehouseByCode(request.getSubWarehouseCode());
        request.setSubWarehouseName(subWarehouseInfo.getSubWarehouseName());
        purchaseOrderFacade.purchaseWarehouseUpdate(request);
        return succeed();
    }


    @Operation(summary = "采购订单作废")
    @DeleteMapping("/purchase/void/{id}")
    public CommonResponse purchaseOrderVoid(@PathVariable("id") Long id) {
        purchaseOrderFacade.purchaseOrderVoid(id);
        return succeed();
    }

    @Operation(summary = "调整采购数量")
    @PutMapping("/purchase/updateLockOrderQty")
    public CommonResponse updateLockOrderQty(@Validated @RequestBody LockOrderQtyUpdateRequest request) {
        request.setCreateUserCode(SPRequestContextHolder.getCurrentSystemUserLoginName());
        request.setCreateUserName(SPRequestContextHolder.getCurrentSystemUserRealName());
        purchaseOrderFacade.updateLockOrderQty(request);
        return succeed();
    }


}